package edu.cmu.cs.cs214.hw9.client.controllers.eventhandlers;

import java.util.List;

import javax.swing.SwingWorker;

import edu.cmu.cs.cs214.hw9.client.controllers.BackendCacheAdapter;
import edu.cmu.cs.cs214.hw9.client.controllers.SessionController;
import edu.cmu.cs.cs214.hw9.client.gui.ProfileScreen;
import edu.cmu.cs.cs214.hw9.datatypes.Status;
import edu.cmu.cs.cs214.hw9.datatypes.User;

/**
 * Goes to a specific user's profile. 
 */
public class GotoProfileHandler extends SessionEventHandler {
	// Encapsulates the profile data, such as the list of status
	// and whether the currently logged in user is a friend of the
	// user whose profile is being viewed.
	private class ProfileData {
		public User target;
		public List<Status> statusList;
		public boolean isFriend;
	}
	
	/**
	 * Request profile data in a separate thread to prevent swing from freezing.
	 */
	private class ProfileSwitchWorker extends SwingWorker<ProfileData, Void> {
		private BackendCacheAdapter model;
		private User currentUser;
		private User profiledUser;
		
		/**
		 * Constructs a request to get profile data for the provided user.
		 * 
		 * @param profiledUser User to get profile data for.
		 */
		public ProfileSwitchWorker(User profiledUser) {
			this.profiledUser = profiledUser;
			currentUser = controller.getCurrentUser();
			model = controller.getModel();
		}
		
		/**
		 * Obtains the profile data from the database.
		 * 
		 * @return Profile data. Note that status list may be empty.
		 */
		public ProfileData doInBackground() {
			User u = (profiledUser != null) ? profiledUser : currentUser;  
			ProfileData result = new ProfileData();
			
			List<Status> statusList = model.getStatuses(u);
			if (statusList.size() > 5) statusList = statusList.subList(0, 5);
			result.statusList = statusList;
			result.isFriend = model.areFriends(currentUser, u);
			result.target = u;
			
			return result;
		}
		
		/**
		 * Redirect the current user to the profiled user's profile.
		 */
		public void done() {
			try {
				ProfileData data = get();
				changeScreen(new ProfileScreen(currentUser, data.target, data.statusList, data.isFriend));
			} catch (Exception e) {
				throw new RuntimeException("Fatal error occured when switching to profile: " + e.getMessage());
			}
		}
	};
	
	/**
	 * Set the current session controller to the provided controller.
	 * 
	 * @param controller Controller to associate with this event handler.
	 */
	public GotoProfileHandler(SessionController controller) { super(controller); }
	
	/**
	 * Create the profile data request and run it in an outside thread.
	 * 
	 * @param param User whose profile data is being viewed by the currently loggedin
	 * 				in user. 
	 */
	public void handleEvent(Object param) {
		ProfileSwitchWorker profileSwitchWorker = new ProfileSwitchWorker((User) param);
		profileSwitchWorker.execute();
	}
}
